﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;

using GISforTT_API;

namespace eGrid_App
{
    /// <summary>
    /// TroubleTicketServerLayer accesses a map service to load trouble ticket data into the application, creates TroubleTicketGraphicLayer to display the tickets, and synchronizes the layers display.
    /// </summary>
    public class TroubleTicketServerLayer : FeatureLayer, ClonableLayer
    {
                
        public delegate void TicketSeverityChangedDelegate(int ticketID, int severity);                
        public event TicketSeverityChangedDelegate TicketSeverity;

        const string ticketLayerName = "TroubleTicketsLayer";

        /// <summary>
        /// Default constructor connects to the server with ticket data and adds this layer to the MapLayersManager instance.
        /// </summary>
        public TroubleTicketServerLayer() : base()
        {
            ID = "ServerTickets";
            Opacity = 1;
            Visible = false;
            Url = "http://asebeast.cpsc.ucalgary.ca:1892/ArcGIS/rest/services/eGridOnline/MapServer/1";
            OutFields.Add("Description");
            OutFields.Add("Severity");
            OutFields.Add("OBJECTID");
            UpdateCompleted += serverTicketsUpdateCompleted;
            MapLayersManager.Instance.MapLayerDeleted += MapLayerDeleted;
            //MapLayersManager.Instance.AddLayer(this);
            BackgroundMapLayer.Instance.MyNonDisplayedLayersMap.Layers.Add(this);
        }

        /// <summary>
        /// Performs additional setup after receiving trouble ticket data, creates a TroubleTicketGraphicLayer for the background map.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void serverTicketsUpdateCompleted(Object sender, EventArgs e)
        {
             MapLayersManager.Instance.AddLayer(CloneLayer());

             List<Bookmark> bookmarks = new List<Bookmark>();

             foreach (Graphic g in Graphics)
             {
                 Bookmark.BookmarkPriority p;
                 switch (g.Attributes["Severity"].ToString())
                 {
                     case "1":
                         p = Bookmark.BookmarkPriority.Low;
                         break;
                     case "2":
                         p = Bookmark.BookmarkPriority.Medium;
                         break;
                     case "3":
                         p = Bookmark.BookmarkPriority.High;
                         break;
                     default:
                         p = Bookmark.BookmarkPriority.Low;
                         break;
                 }

                 Bookmark b = new Bookmark((g.Geometry as MapPoint), g.Attributes["Description"].ToString(), g.Attributes["OBJECTID"].ToString(),  p);
                 bookmarks.Add(b);

             }
             BookmarkList.Instance.initializeBookmarkList(bookmarks);
        }

        /// <summary>
        /// Clonelayer returns a TroubleTicketGraphicLayer instead of a TroubleTicketServerLayer, not actually a clone in this case.
        /// </summary>
        /// <returns></returns>
        public Layer CloneLayer()
        {
            TroubleTicketGraphicLayer ticketsLayer = new TroubleTicketGraphicLayer();
                ticketsLayer.Visible = true;
                ticketsLayer.Opacity = 1;
                ticketsLayer.ID = ticketLayerName;
                ticketsLayer.tickets = new Dictionary<int, TroubleTicket>();

                TicketSeverity += ticketsLayer.ChangeTicketGraphic; 

                foreach (Graphic g in Graphics)
                {
                    TroubleTicket newTicket = new TroubleTicket();
                    newTicket.Geometry = Geometry.Clone(g.Geometry);
                    newTicket.MouseLeftButtonUp += troubleTicketLeftClick;
                    newTicket.Priority = (int)g.Attributes["Severity"];
                    newTicket.originalGraphic = g;

                    ticketsLayer.Graphics.Add(newTicket);
                    ticketsLayer.tickets.Add((int)g.Attributes["OBJECTID"], newTicket);
                    ticketsLayer.serverLayer = this;
                }

                return ticketsLayer;
        }

        /// <summary>
        /// Notify TroubleTicketServerLayers that a ticket severity has changed.
        /// </summary>
        /// <param name="ticketID"></param>
        /// <param name="severity"></param>
        public void TicketSeverityChanged(int ticketID, int severity)
        {
            if (TicketSeverity != null)
            {
                TicketSeverity(ticketID, severity);
            }
        }

        /// <summary>
        /// Open a FeatureInfoTip when a trouble ticket is tapped or clicked on the background map
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void troubleTicketLeftClick(Object sender, EventArgs e)
        {
            TroubleTicket g = (TroubleTicket)sender;
            FeatureInfoTip fit = new FeatureInfoTip(g, this);

            Point point = new Point();
            point = BackgroundMapLayer.Instance.getBackgroundMap().Map.MapToScreen((MapPoint)g.Geometry);
            fit.Orientation = 0.0;
            fit.Center = point;

            BackgroundMapLayer.Instance.AddScatterViewItem(fit);
        }


        
        /// <summary>
        /// If the cloned TroubleTicketGraphicLayer is removed from the MapLayerManager, this parent layer should go too.
        /// </summary>
        /// <param name="aMapLayer"></param>
        public void MapLayerDeleted(Layer aMapLayer)
        {
            if (aMapLayer.ID == ticketLayerName)
            {
                MapLayersManager.Instance.MapLayerDeleted -= MapLayerDeleted;
                BackgroundMapLayer.Instance.MyNonDisplayedLayersMap.Layers.Remove(this);
            }
        }

    }
}
